import Vue from "vue";
import Axios from "axios";
import Qs from "qs";
import setting from "@/setting";
import AbJwtSetting from "@/service/common/ab-jwt-setting.js";
import JSbridge from "@/service/common/GZBJSBridge";
import router from '@/router';

var __ctx = setting.ctx;
const shortTips = setting.shortTips
var jwtHeader = window.AbJwtSetting.getHeader();
var headers = {};
if (jwtHeader) {
  headers[window.AbJwtSetting.headerName] = jwtHeader;
}
var axios = Axios.create({
  baseURL: "", //配置请求地址默认则直接请求 与前端地址相同的 domain
  timeout: "90000", //请求超时时间
  //header传值，例如：Authorization
  headers: headers
});
axios.defaults.withCredentials = true;

axios.interceptors.request.use(function(request) {
  request.credentials = true;
  return request;
});

// 设置通用的拦截器
axios.interceptors.response.use(
  function(response) {
    let tips = ''
    const data = response.data
    if (!data.isOk && data.code) {
      if (shortTips) {
        tips = `接口请求失败【${data.code}】`
      } else {
        tips = data.msg
      }
    }
    if (tips && response.data.code !== "401") {   //response.data.code !== "401" 401登录失效的时候不提示错误直接跳转登录了  2023-12-26小程序演示用
      Vue.$vux.toast.show({
        type: "warn",
        text: tips,
        time: 6000
      });
    }
    if (response.data && !response.data.isOk && response.data.code === "401") {
      if (process.env.Equipment == 'appBank') {
        let params = {
          method: "quit"
        };
        setTimeout(() => {
          JSbridge.nativeFunc(params);
        }, 2000)
      }
      //Vue.toLogin();
      // if(response.data.code === "401"){  //登录超时去登录页
      //   router.push({
      //     path: '/login', 
      //     query:{
      //       redirect: router.history.current.path == '/loanPage/productDetail' || router.history.current.path == '/loanPage/intentRegistration' || router.history.current.path == '/loanPage/QRCodeForProduct' ? router.history.current.fullPath : '',  //自动登录且为产品详情页或意向登记页时记录历史页面   跳转登录之后跳转回产品详情页
      //       defaultLogin: true, account: 'wxBank', password: '1', userRole: '客户'
      //     }
      //   });  //默认登录defaultLogin： true   账号密码  角色userRole：客户和客户经理两项  update2023-12-25
      //   return;
      // }
    }
    return response;
  },
  function(error) {
    //通用异常
    let tips = '系统异常，请稍后再试！'

    if (error.message.includes("timeout")) {
      tips = '系统响应超时，请稍后再试！'
    }
    Vue.$vux.toast.show({
      type: "warn",
      text: tips,
      time: 6000
    });
    return Promise.reject(error);
  }
);

function encodeData(data, url) {
  return new Promise((resolve, reject) => {
    // 判断加密开关是否开启
    let cryptoSwitch = setting.cryptoSwitch
    if (!cryptoSwitch) {
      resolve({
        data: data,
        headers: {},
        encodeKeys: {
          zak: '',
          zek: '',
          cbc: ''
        },
      });
      return;
    }
    // 判断是否在接口加密白名单中（免加密）
    let whiteStr = setting.apiWhiteList
    if (whiteStr) {
      let whiteList = whiteStr.split(",");
      let isWhiteUrl = whiteList.findIndex((d) => {
        return url.indexOf(d) != -1;
      });
      if (isWhiteUrl != -1) {
        resolve({
          data: data,
          headers: {},
          encodeKeys: {
            zak: '',
            zek: '',
            cbc: ''
          },
        });
        return;
      }
    }

    var dataBase64 = iSec_js_sdk.isec_crypto_utf8_to_base64(
      JSON.stringify(data)
    ).data; // 请求数据转Base64后
    // ar dataBase64 = (iSec_js_sdk.isec_crypto_utf8_to_base64(data)).data; // 请求数据转Base64后
    // var dataBase64 = JSON.stringify(data); // 请求数据转Base64后
    var publicKey = iSec_js_sdk.isec_crypto_hex_to_base64(
      "04" + setting.publicKey
    ).data;
    var zekStr = iSec_js_sdk.isec_crypto_generate_symm_key(256); // 加密对称秘钥Zek
    var zakStr = iSec_js_sdk.isec_crypto_generate_symm_key(256); // 加密对称秘钥Zak
    var cbcStr = iSec_js_sdk.isec_crypto_generate_symm_key(256); // CBC向量
    // 获取SM4加密报文传递的参数
    var sm4RequestData = {
      plaintext: dataBase64,
      key: zekStr.data.key,
      iv: cbcStr.data.key,
      mode: "CBC",
      padding: "pkcs7padding",
    };
    // console.log("dataBase64 ==>", dataBase64);
    // console.log("publicKey ==>", publicKey);
    // console.log("zekStr ==>", zekStr.data.key);
    // console.log("zakStr ==>", zakStr.data.key);
    // console.log("cbcStr ==>", cbcStr.data.key);
    var sm4Response = iSec_js_sdk.isec_crypto_sm4_encrypt(sm4RequestData);
    var sm4 = sm4Response.data;
    // console.log("sm4Response ==>", sm4Response);
    // console.log("sm4 ==>", sm4);
    /* var sm3RequestData = {
       plaintext: dataBase64,
       isec_digest: "sm3",
     };
     var sm3Response = iSec_js_sdk.isec_crypto_digest(sm3RequestData);
     var sm3 = iSec_js_sdk.isec_crypto_utf8_to_base64(sm3Response.data);*/
    // console.log("sm3 ==>", sm3);
    /* var hmacRequestData = {    //计算hmac
       plaintext: sm3,
       isec_digest: "sm3",
       key: zakStr.data.key,
     };
     var hamcResponse = iSec_js_sdk.isec_crypto_hmac(hmacRequestData);
     var hmac = iSec_js_sdk.isec_crypto_base64_to_hex(hamcResponse.data).data; */
    var hmac = ''
    // console.log("hmac ==>", hmac);
    var sm2ZakRequestData = {
      plaintext: zakStr.data.key,
      publicKey: publicKey,
    };
    var sm2ZakResponse = iSec_js_sdk.isec_crypto_sm2_encrypt(sm2ZakRequestData);
    var sm2Zak = iSec_js_sdk.isec_crypto_base64_to_hex(sm2ZakResponse.data)
      .data;
    // console.log("sm2Zak ==>", sm2Zak);
    var sm2ZekRequestData = {
      plaintext: zekStr.data.key,
      publicKey: publicKey,
    };
    var sm2ZekResponse = iSec_js_sdk.isec_crypto_sm2_encrypt(sm2ZekRequestData);
    var sm2Zek = iSec_js_sdk.isec_crypto_base64_to_hex(sm2ZekResponse.data)
      .data;
    // console.log("sm2Zek ==>", sm2Zek);
    // console.log(request)
    let headers = {};
    headers["X-GZB-zak"] = sm2Zak;
    headers["X-GZB-zek"] = sm2Zek;
    headers["X-GZB-mac"] = hmac;
    headers["X-GZB-sm4-iv"] = iSec_js_sdk.isec_crypto_base64_to_hex(
      cbcStr.data.key
    ).data;
    resolve({
      data: {
        sm4
      },
      headers,
      encodeKeys: {
        zak: zakStr.data,
        zek: zekStr.data,
        cbc: cbcStr.data
      },
    });
    // data = { sm4 };
  });
}

function decodeData(encodeKeys, cryptData, hmac) {
  // let key = response.config.url.split("/");
  // key = key[key.length - 1];
  // console.log("decodeData ==>", cryptData);
  if (encodeKeys.zek && cryptData.encryptData) {
    if (hmac) {}
    let encryptData = iSec_js_sdk.isec_crypto_hex_to_base64(
      cryptData.encryptData
    );
    // console.log("ciphertext ==>", encryptData.data);
    // console.log("key ==>", encodeKeys.zek);
    // console.log("iv ==>", encodeKeys.cbc.key);
    let visibleData = iSec_js_sdk.isec_crypto_sm4_decrypt({
      ciphertext: encryptData.data,
      key: encodeKeys.zek.key,
      iv: encodeKeys.cbc.key,
      mode: "CBC",
      padding: "pkcs7padding",
      isutf8: true,
    });
    // console.log("visibleData ==>", JSON.parse(visibleData.data));
    cryptData = JSON.parse(visibleData.data);
  }
  return cryptData;
}

// baseService 基础服务
var BaseService = {
  get: function(url) {
    return new Promise((resolve, reject) => {
      axios
        .get(url)
        .then(response => {
          resolve(response.data);
        })
        .catch(error => {
          console.log("请求失败：", error);
          reject(error);
        });
    });
  },
  getParams: function(url, obj) {
    //带参数的get请求
    return new Promise((resolve, reject) => {
      axios
        .get(url, {
          params: obj
        })
        .then(response => {
          resolve(response.data);
        })
        .catch(error => {
          console.log("请求失败：", error);
          reject(error);
        });
    });
  },
  post: function(url, data) {
    if (!data) data = {};

    return new Promise((resolve, reject) => {
      encodeData(data, url).then((encryptData) => {
        axios
          .post(url, encryptData.data, {
            headers: encryptData.headers
          })
          .then(res => {
            let responseData = decodeData({
                zak: encryptData.encodeKeys.zak,
                zek: encryptData.encodeKeys.zek,
                cbc: encryptData.encodeKeys.cbc,
              },
              res.data,
              ""
            );
            resolve(responseData);
          })
          .catch(error => {
            // console.log("请求失败：", error);
            // reject(error);
          });
      })
    });
  },
  // form-data格式化
  postForm: function(url, data) {
    if (!data) data = {};

    return new Promise((resolve, reject) => {
      encodeData(data, url).then((encryptData) => {
        let headers = encryptData.headers;
        headers["Content-Type"] =
          "application/x-www-form-urlencoded; charset=utf-8";
        axios
          .post(url, encryptData.data, {
            transformRequest: this.jsonToFormData,
            headers: headers
          })
          .then(res => {
            let responseData = decodeData({
                zak: encryptData.encodeKeys.zak,
                zek: encryptData.encodeKeys.zek,
                cbc: encryptData.encodeKeys.cbc,
              },
              res.data,
              ""
            );
            resolve(responseData);
          })
          .catch(error => {
            console.log("请求失败：", error);
            reject(error);
          });
      })
    });
  },
  jsonToFormData: function(data) {
    data = Qs.stringify(data, {
      arrayFormat: "brackets"
    }); // qs.stringify(params)
    return data;
  },
  delete: function(url) {
    return new Promise((resolve, reject) => {
      axios
        .delete(url)
        .then(response => {
          resolve(response.data);
        })
        .catch(error => {
          console.log("请求失败：", error);
          reject(error);
        });
    });
  }
};

// 数组服务
var ArrayToolService = {
  //上移按钮
  up: function(idx, list) {
    if (idx < 1) {
      return;
    }
    var t = list[idx - 1];
    list[idx - 1] = list[idx];
    list[idx] = t;
  },
  //下移按钮
  down: function(idx, list) {
    if (idx >= list.length - 1) {
      return;
    }
    var t = list[idx + 1];
    list[idx + 1] = list[idx];
    list[idx] = t;
  },
  resumeSn: function(list) {
    for (var k = 0; k < list.length; k++) {
      list[k].sn = k;
    }
    return list;
  },
  /**
   * idx 原位置
   * num 目标位置
   * list 数组
   */
  moveToNum: function(idx, target, list) {
    if (target == -1) {
      target = 0;
    } else if (idx >= target) {
      target = target + 1;
    }
    var t = list.splice(idx, 1);
    list.insert(target, t[0]);
    this.resumeSn(list);
  },
  //默认ngModel turnToIndex
  turnTo: function(rowScope, list) {
    var toIndex = rowScope.turnToIndex - 1;
    if (!rowScope.turnToIndex || toIndex < 0 || toIndex >= list.length) return;

    var index = rowScope.$index;
    if (toIndex == index) return;

    var row = list.splice(index, 1);
    list.insert(toIndex, row[0]);

    rowScope.turnToIndex = "";
  },
  //删除按钮
  del: function(idx, list) {
    list.splice(idx, 1);
  },
  //找到指定元素的未知
  idxOf: function(val, list) {
    for (var i = 0; i < list.length; i++) {
      if (list[i] == val) return i;
    }
    return -1;
  },
  //删除指定元素
  remove: function(val, list) {
    var idx = this.idxOf(val, list);
    if (idx > -1) {
      list.splice(idx, 1);
    }
  },
  //置顶
  top: function(idx, list) {
    if (idx >= list.length || idx < 1) {
      return;
    }
    //逐个交换
    for (var i = 0; i < idx; i++) {
      var temp = list[i];
      list[i] = list[idx];
      list[idx] = temp;
    }
  },
  //置底
  bottom: function(idx, list) {
    if (idx >= list.length - 1 || idx < 0) {
      return;
    }
    //逐个交换
    for (var i = list.length - 1; i > idx; i--) {
      var temp = list[i];
      list[i] = list[idx];
      list[idx] = temp;
    }
  }
};

export default {
  // 全局安装时候
  install(Vue) {
    Vue.baseService = BaseService;
    Vue.arrayTools = ArrayToolService;
    Vue.__ctx = __ctx;
    Vue.prototype.arrayTools = ArrayToolService;
    Vue.prototype.baseService = BaseService;
    Vue.prototype.__ctx = __ctx;
  },
  baseService: BaseService,
  arrayTools: ArrayToolService
};

export const baseService = BaseService;
export const arrayTools = ArrayToolService;